// utils/fileDownload.js - 文件下载工具类
import { ElMessage } from 'element-plus'

/**
 * 文件下载工具类
 */
export class FileDownloadUtil {
    /**
     * 从Blob下载文件
     * @param {Blob} blob - 文件Blob对象
     * @param {string} defaultFilename - 默认文件名
     * @param {Object} response - HTTP响应对象（可选）
     * @returns {Promise<boolean>} 下载是否成功
     */
    static async downloadFromBlob(blob, defaultFilename, response = null) {
        try {
            // 验证Blob对象
            if (!blob || !(blob instanceof Blob)) {
                throw new Error('无效的文件数据')
            }

            // 检查文件大小
            if (blob.size === 0) {
                throw new Error('文件为空')
            }

            // 创建下载链接
            const url = window.URL.createObjectURL(blob)
            const link = document.createElement('a')
            link.href = url
            link.style.display = 'none'

            // 获取文件名
            const filename = extractFilename(response, defaultFilename)
            link.download = filename

            // 添加到DOM并点击下载
            document.body.appendChild(link)
            link.click()

            // 清理资源
            document.body.removeChild(link)
            window.URL.revokeObjectURL(url)

            console.log(`文件下载成功: ${filename}`)
            return true
        } catch (error) {
            console.error('文件下载失败:', error)
            ElMessage.error(`文件下载失败: ${error.message}`)
            return false
        }
    }

    /**
     * 从响应头中提取文件名
     * @param {Object} response - HTTP响应对象
     * @param {string} defaultFilename - 默认文件名
     * @returns {string} 文件名
     */
    static extractFilename(response, defaultFilename) {
        if (!response || !response.headers) {
            return defaultFilename
        }

        // 获取Content-Disposition头
        const contentDisposition = response.headers['content-disposition'] ||
            response.headers['Content-Disposition']

        if (!contentDisposition) {
            return defaultFilename
        }

        try {
            // 尝试匹配RFC 5987格式 (filename*=UTF-8'')
            const rfc5987Match = contentDisposition.match(/filename\*=UTF-8''([^;]+)/)
            if (rfc5987Match && rfc5987Match[1]) {
                return decodeURIComponent(rfc5987Match[1])
            }

            // 尝试匹配传统格式 (filename="...")
            const traditionalMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)
            if (traditionalMatch && traditionalMatch[1]) {
                let filename = traditionalMatch[1].replace(/['"]/g, '')

                // 尝试URL解码
                try {
                    filename = decodeURIComponent(filename)
                } catch (e) {
                    // 如果解码失败，使用原始文件名
                    console.warn('文件名解码失败，使用原始文件名:', filename)
                }

                return filename
            }
        } catch (error) {
            console.warn('提取文件名失败:', error)
        }

        return defaultFilename
    }

    /**
     * 验证Excel文件
     * @param {Blob} blob - 文件Blob对象
     * @returns {Promise<boolean>} 验证结果
     */
    static async validateExcelFile(blob) {
        try {
            // 检查文件大小
            if (blob.size === 0) {
                throw new Error('文件为空')
            }

            // 检查文件头（Excel文件应该以PK开头）
            const buffer = await blob.slice(0, 4).arrayBuffer()
            const header = new Uint8Array(buffer)

            // XLSX文件以PK开头 (0x50, 0x4B)
            if (header[0] === 0x50 && header[1] === 0x4B) {
                return true
            }

            // XLS文件以特定字节开头
            if (header[0] === 0xD0 && header[1] === 0xCF) {
                return true
            }

            console.warn('文件格式可能不是标准Excel格式')
            return true // 仍然尝试下载
        } catch (error) {
            console.error('验证Excel文件失败:', error)
            return false
        }
    }

    /**
     * 下载Excel文件的便捷方法
     * @param {Blob} blob - Excel文件Blob对象
     * @param {string} defaultFilename - 默认文件名
     * @param {Object} response - HTTP响应对象（可选）
     * @returns {Promise<boolean>} 下载是否成功
     */
    static async downloadExcel(blob, defaultFilename, response = null) {
        try {
            // 验证Excel文件
            const isValid = await validateExcelFile(blob)
            if (!isValid) {
                throw new Error('Excel文件格式验证失败')
            }

            // 确保文件名有.xlsx扩展名
            if (!defaultFilename.endsWith('.xlsx') && !defaultFilename.endsWith('.xls')) {
                defaultFilename += '.xlsx'
            }

            return await downloadFile(blob, defaultFilename, response)
        } catch (error) {
            console.error('下载Excel文件失败:', error)
            ElMessage.error(`下载Excel文件失败: ${error.message}`)
            return false
        }
    }
}

// 导出便捷函数
export const downloadFile = FileDownloadUtil.downloadFromBlob
export const extractFilename = FileDownloadUtil.extractFilename
export const downloadExcel = FileDownloadUtil.downloadExcel
export const validateExcelFile = FileDownloadUtil.validateExcelFile